package com.crayon2f.test.xml;

import org.apache.commons.lang3.StringUtils;
import org.junit.Test;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.StringReader;
import java.net.URL;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;

public class DynamicDirectoryImageDownloader {
    
    // 数据库配置
    private static final String DB_URL = "jdbc:mysql://10.39.46.244:3306/basedata";
    private static final String DB_USER = "basedata_reader";
    private static final String DB_PASSWORD = "GFISAoTk3ZVuQV8b9CElBRS8";

    // 基础URL配置
    private static final String BASE_IMAGE_URL = "http://build-model.fnw.enncloud.cn/";
    
    // 本地存储根目录
    private static final String LOCAL_STORAGE_ROOT = "D:\\download\\shape_images";
    
    // 用于跟踪目录和图片数量
    private static final Map<String, AtomicInteger> dirCountMap = new ConcurrentHashMap<>();
    private static final Map<String, File> originalDirs = new ConcurrentHashMap<>();

    public static void main(String[] args) {
        Connection conn = null;
        Statement stmt = null;
        ResultSet rs = null;
        
        try {
            // 1. 注册MySQL驱动
            Class.forName("com.mysql.cj.jdbc.Driver");
            
            // 2. 连接MySQL数据库
            conn = DriverManager.getConnection(DB_URL, DB_USER, DB_PASSWORD);
            stmt = conn.createStatement();
            
            // 3. 查询包含shape字段的表
            String sql = "SELECT shape,name FROM graphic_meta where shape like '%image%'";
            rs = stmt.executeQuery(sql);
            Map<String, Integer> map = new HashMap<>();
            // 4. 遍历结果集
            while (rs.next()) {
                String shapeXml = rs.getString("shape");
                String name = rs.getString("name");
                try {
                    // 5. 解析shape XML
                    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
                    DocumentBuilder builder = factory.newDocumentBuilder();
                    Document doc = builder.parse(new InputSource(new StringReader(shapeXml)));
                    
                    // 获取shape根元素
                    Element shape = doc.getDocumentElement();
                    
                    // 6. 从shape属性中获取cimName和cimCode
                    String cimName = shape.getAttribute("cimName");
                    String cimCode = shape.getAttribute("cimCode");
                    
                    if (cimName.isEmpty() || cimCode.isEmpty()) {
                        System.out.println("跳过: shape缺少cimName或cimCode属性");
                        continue;
                    }
                    
                    // 7. 解析image标签
                    NodeList imageNodes = doc.getElementsByTagName("image");
                    if (imageNodes.getLength() == 0) {
                        System.out.println("跳过: 没有找到image标签");
                        continue;
                    }

                    Element image = (Element) imageNodes.item(0);
                    String imageSrc = image.getAttribute("src");
                    if (imageSrc.isEmpty()) {
                        System.out.println("跳过: image标签缺少src属性");
                        continue;
                    }
                    
                    // 8. 生成基础目录名
                    String dynamicDirName = cimName + "(" + cimCode + ")";


                    if (map.containsKey(dynamicDirName)) {
                        int integer = map.get(dynamicDirName);
                        map.put(dynamicDirName, ++integer);
                    } else {
                        map.put(dynamicDirName, 1);
                    }
////                    // 9. 获取或创建目录计数器
////                    AtomicInteger counter = dirCountMap.computeIfAbsent(baseDirName, k -> new AtomicInteger(0));
////                    int currentCount = counter.incrementAndGet();
////
////                    // 10. 创建带数量的目录名
////                    String dynamicDirName = baseDirName + "-" + currentCount;
                    String imageUrl = buildFullImageUrl(imageSrc).replaceAll("(\\s)+", StringUtils.EMPTY);
                    if (imageSrc.contains("https:")) {
                        imageUrl = imageSrc;
                    }
                    String localPath = buildLocalPath(dynamicDirName, name, imageSrc.substring(imageSrc.lastIndexOf(".")));

                    // 11. 下载图片
                    boolean success = downloadImage(imageUrl, localPath);
                    if (success) {
                        System.out.println("下载成功: " + imageUrl + " -> " + localPath);

////                        // 记录原始目录名和实际目录的映射
////                        originalDirs.put(baseDirName, new File(LOCAL_STORAGE_ROOT, dynamicDirName));
                    } else {
////                        // 如果下载失败，减少计数器
////                        counter.decrementAndGet();
                    }
                    
                } catch (Exception e) {
                    System.err.println("XML解析错误: " + e.getMessage());
                    e.printStackTrace();
                }
            }
            
            // 12. 打印最终目录结构
            printFinalDirectoryStructure();

//            System.out.println(map);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 关闭资源
            try { if (rs != null) rs.close(); } catch (SQLException e) { e.printStackTrace(); }
            try { if (stmt != null) stmt.close(); } catch (SQLException e) { e.printStackTrace(); }
            try { if (conn != null) conn.close(); } catch (SQLException e) { e.printStackTrace(); }
        }
    }
    
    /**
     * 构建完整的图片URL
     */
    private static String buildFullImageUrl(String srcPath) {
        String normalizedSrc = srcPath.startsWith("/") ? srcPath.substring(1) : srcPath;
        return BASE_IMAGE_URL + "/" + normalizedSrc;
    }
    
    /**
     * 构建本地存储路径
     */
    private static String buildLocalPath(String dirName, String name, String sub) {
        File dir = new File(LOCAL_STORAGE_ROOT, dirName);
        if (!dir.exists()) {
            dir.mkdirs();
        }
        
//        String filename = srcPath.substring(srcPath.lastIndexOf('/') + 1) + "/";
        return new File(dir, name.replace("mxGraph.", "").replace("mxgraph.","") + sub).getAbsolutePath();
    }
    
    /**
     * 下载图片到本地
     */
    private static boolean downloadImage(String imageUrl, String localPath) {
        try (InputStream in = new URL(imageUrl).openStream();
             FileOutputStream out = new FileOutputStream(localPath)) {
            
            byte[] buffer = new byte[4096];
            int bytesRead;
            while ((bytesRead = in.read(buffer)) != -1) {
                out.write(buffer, 0, bytesRead);
            }
            return true;
            
        } catch (Exception e) {
            System.err.println("下载失败: " + imageUrl + " - " + e.getMessage());
            return false;
        }
    }
    
    /**
     * 打印最终目录结构
     */
    private static void printFinalDirectoryStructure() {

        File file = new File(LOCAL_STORAGE_ROOT);
        File[] files = file.listFiles();
        for (File dir : files) {
            int length = dir.list().length;
//            dir.renameTo(new File(String.format(dir.getAbsolutePath() + "(%d)", length)));
            String absolutePath = dir.getAbsolutePath();
            String substring = absolutePath.substring(0, absolutePath.indexOf(")") + 1);
            String name = String.format("%s[%d]", substring, length);
            dir.renameTo(new File(name));
//            System.out.println(absolutePath);
        }
    }

    @Test
    public void test() {

        printFinalDirectoryStructure();
    }
}